#include "include/muduo/net/TcpClient.h"
#include "include/muduo/net/EventLoopThread.h"
#include "include/muduo/net/TcpConnection.h"
#include "include/muduo/base/CountDownLatch.h"
#include <iostream>
#include <string>
#include <functional>
#include <memory>

class TranslateClient
{
public:
    TranslateClient(const std::string &serverip, uint16_t serverport)
        : _latch(1),
          _tcpclient(_loopthread.startLoop(), muduo::net::InetAddress(serverip, serverport), "翻译客户端")
    {
        _tcpclient.setConnectionCallback(std::bind(&TranslateClient::OnConnectionCallback, this, std::placeholders::_1));
        _tcpclient.setMessageCallback(std::bind(&TranslateClient::OnMessageCallback, this, std::placeholders::_1,
                                     std::placeholders::_2,
                                     std::placeholders::_3));
                                     
    }
    void Connect()
    {
        _tcpclient.connect();
        _latch.wait(); // 阻塞住
    }
    void Send(const std::string &message)
    {
        if (_conn->connected()) // 因为是异步
            _conn->send(message);
        else
            std::cout << "send false, connect droped" << std::endl;
    }

private:
    void OnConnectionCallback(const muduo::net::TcpConnectionPtr& conn)
    {
        if (conn->connected())
        {
            _latch.countDown();
            _conn = conn;
        }
        else
        {
            _conn.reset();
        }
    }
    void OnMessageCallback(const muduo::net::TcpConnectionPtr& conn, muduo::net::Buffer* buffer, muduo::Timestamp time)
    {
        std::cout << "response: " << buffer->retrieveAllAsString() << std::endl;
    }

private:
    muduo::CountDownLatch _latch;
    muduo::net::EventLoopThread _loopthread;
    muduo::net::TcpClient _tcpclient;
    muduo::net::TcpConnectionPtr _conn;
};

int main(int argc, char *argv[])
{
    std::unique_ptr<TranslateClient> client = std::make_unique<TranslateClient>(argv[1], std::stoi(argv[2]));
    client->Connect();
    while (true)
    {
        std::string message;
        getline(std::cin, message);
        client->Send(message);
    }
    return 0;
}
